<script setup>
/**
 * 类型定义查看器组件
 * 用于动态加载和展示TypeScript类型定义内容
 * 支持实时监听文件变化，提供搜索、复制功能
 */
import { ref, onMounted, computed, watch, onUnmounted } from 'vue'
import { useData } from 'vitepress'
import CopyButton from './CopyButton.vue'
import CodeBlock from './CodeBlock.vue'

// 状态变量
const loading = ref(true)
const error = ref(null)
const types = ref([])
const searchQuery = ref('')
const selectedType = ref(null)
const typeContent = ref('')
const contentLoading = ref(false)
const modifiedTypes = ref([])
const monitorStatus = ref('active')
const activeGroups = ref([])
const showSuggestions = ref(false)
const activeSuggestionIndex = ref(-1)

// 获取当前路由信息
const { page } = useData()

// 监听类型文件变化
let monitorInterval = null
let lastCheckTime = Date.now()

// 过滤后的类型
const filteredTypes = computed(() => {
  if (!searchQuery.value) return types.value
  
  return types.value.filter(type => 
    type.name.toLowerCase().includes(searchQuery.value.toLowerCase())
  )
})

// 按类型前缀分组
const typeGroups = computed(() => {
  const groups = {}
  
  filteredTypes.value.forEach(type => {
    const prefix = type.name.split('_')[0].replace('.ts', '')
    if (!groups[prefix]) {
      groups[prefix] = []
    }
    groups[prefix].push(type)
  })
  
  return Object.entries(groups).map(([prefix, items]) => ({
    prefix,
    types: items
  }))
})

// 搜索建议列表
const searchSuggestions = computed(() => {
  if (!searchQuery.value || searchQuery.value.length < 1) return []
  
  const query = searchQuery.value.toLowerCase()
  return types.value
    .filter(type => type.name.toLowerCase().includes(query))
    .slice(0, 5) // 最多显示5个建议
})

// 初始化
onMounted(async () => {
  await fetchTypes()
  startMonitoring()
  
  // 如果URL中有类型名，自动选择该类型
  const typeName = window.location.hash.substring(1)
  if (typeName) {
    // 尝试从types列表中找到匹配的类型
    const exactMatch = types.value.find(t => t.name.replace('.ts', '') === typeName)
    if (exactMatch) {
      selectType(exactMatch)
    } else {
      // 尝试查找名称中包含hash的类型
      const containMatch = types.value.find(t => t.name.toLowerCase().includes(typeName.toLowerCase()))
      if (containMatch) {
        selectType(containMatch)
      } else {
        console.warn(`未找到类型: ${typeName}`)
        // 处理加载中类型的情况，类型尚未加载完毕
        setTimeout(() => {
          const delayedMatch = types.value.find(t => t.name.replace('.ts', '') === typeName || 
            t.name.toLowerCase().includes(typeName.toLowerCase()))
          if (delayedMatch) {
            selectType(delayedMatch)
          }
        }, 1000) // 延迟1秒尝试获取类型
      }
    }
  }
})

/**
 * 获取所有类型定义信息
 * 从API端点加载类型列表
 */
async function fetchTypes() {
  try {
    loading.value = true
    error.value = null
    
    try {
      // 尝试从API获取类型列表
      const response = await fetch('/api/types')
      
      // 检查响应是否为JSON格式
      const contentType = response.headers.get('content-type')
      if (!contentType || !contentType.includes('application/json')) {
        console.warn('API响应不是JSON格式:', contentType)
        throw new Error('API响应格式错误')
      }
      
      if (!response.ok) {
        throw new Error('获取类型定义信息失败: ' + response.status)
      }
      
      const data = await response.json()
      
      if (data.error) {
        throw new Error(data.error)
      }
      
      // 确保返回的数据包含types数组
      if (!data.types || !Array.isArray(data.types)) {
        throw new Error('API返回的数据格式不正确')
      }
      
      types.value = data.types
    } catch (apiErr) {
      console.error('API加载类型定义失败，使用默认数据:', apiErr)
      
      // 使用内置默认数据
      types.value = [
        {
          name: "sys_user.ts",
          description: "系统用户类型定义",
          path: "/types/sys_user.ts",
          updateTime: "2024-03-27T12:00:00Z"
        },
        {
          name: "sys_role.ts",
          description: "角色类型定义",
          path: "/types/sys_role.ts",
          updateTime: "2024-03-27T12:00:00Z"
        },
        {
          name: "sys_menu.ts",
          description: "菜单类型定义",
          path: "/types/sys_menu.ts", 
          updateTime: "2024-03-27T12:00:00Z"
        },
        {
          name: "sys_config.ts",
          description: "系统配置类型定义",
          path: "/types/sys_config.ts",
          updateTime: "2024-03-27T12:00:00Z"
        }
      ]
    }
    
    // 初始打开第一个分组
    if (typeGroups.value.length > 0 && activeGroups.value.length === 0) {
      activeGroups.value = [typeGroups.value[0].prefix]
    }
    
    loading.value = false
  } catch (err) {
    loading.value = false
    error.value = err.message || '获取类型定义信息失败'
    console.error('获取类型定义错误:', err)
  }
}

/**
 * 选择类型定义
 * @param {Object} type 类型对象
 */
async function selectType(type) {
  try {
    if (selectedType.value === type.name) return
    
    selectedType.value = type.name
    contentLoading.value = true
    typeContent.value = ''
    
    // 更新URL hash，方便分享
    window.location.hash = type.name.replace('.ts', '')
    
    // 直接读取原始类型文件内容
    try {
      console.log(`尝试加载类型文件: ${type.name}`)
      
      // 使用/raw-types/路径
      const url = `/raw-types/${type.name}`
      console.log(`请求URL: ${url}`)
      
      const response = await fetch(url)
      
      // 检查内容类型，确保是文本类型
      const contentType = response.headers.get('content-type')
      if (contentType && contentType.includes('text/html')) {
        console.warn('获取到HTML内容而不是TS文件:', contentType)
        throw new Error('返回了HTML而不是预期的TypeScript文件')
      }
      
      if (!response.ok) {
        throw new Error(`获取类型"${type.name}"内容失败: ${response.status} ${response.statusText}`)
      }
      
      const content = await response.text()
      
      // 检查一下内容是否是HTML或包含DOCTYPE（这表明可能返回了错误页面）
      if (content.includes('<!DOCTYPE') || content.includes('<html')) {
        console.warn('内容疑似HTML而非TypeScript:', content.substring(0, 100))
        throw new Error('返回了HTML页面而不是TypeScript内容')
      }
      
      // 检查内容是否为空
      if (!content.trim()) {
        throw new Error('类型定义内容为空')
      }
      
      typeContent.value = content
      console.log(`成功加载类型内容, 长度=${content.length}字节`)
    } catch (err) {
      console.error('获取类型定义内容网络错误:', err)
      
      // 使用内置demo数据
      if (type.name === 'sys_user.ts') {
        typeContent.value = `/**
 * 系统用户对象
 * 对应表: sys_user
 */
export interface SysUser {
  /**
   * 用户ID - 主键
   */
  user_id: number;
  
  /**
   * 部门ID - 外键关联sys_dept表
   */
  dept_id?: number;
  
  /**
   * 用户账号 - 登录名，唯一
   */
  user_name: string;
  
  /**
   * 用户昵称 - 显示名称
   */
  nick_name: string;
  
  /**
   * 用户类型 - sys=系统用户，gen=一般用户
   */
  user_type?: string;
  
  /**
   * 用户邮箱 - 唯一
   */
  email?: string;
  
  /**
   * 手机号码 - 唯一
   */
  phone_number?: string;
  
  /**
   * 用户性别 - 0=男，1=女，2=未知
   */
  gender?: '0' | '1' | '2';
}`
      } else if (type.name === 'sys_role.ts') {
        typeContent.value = `/**
 * 角色对象
 * 对应表: sys_role
 */
export interface SysRole {
  /**
   * 角色ID - 主键
   */
  role_id: number;
  
  /**
   * 角色名称 - 唯一
   */
  role_name: string;
  
  /**
   * 角色权限字符串 - 唯一
   */
  role_key: string;
  
  /**
   * 显示顺序
   */
  role_sort: number;
  
  /**
   * 状态 - 0=正常，1=停用
   */
  status?: '0' | '1';
}`
      } else if (type.name === 'sys_menu.ts') {
        typeContent.value = `/**
 * 菜单对象
 * 对应表: sys_menu
 */
export interface SysMenu {
  /**
   * 菜单ID - 主键
   */
  menu_id: number;
  
  /**
   * 菜单名称
   */
  menu_name: string;
  
  /**
   * 父菜单ID
   */
  parent_id?: number;
  
  /**
   * 显示顺序
   */
  order_num: number;
  
  /**
   * 路由地址
   */
  path?: string;
  
  /**
   * 组件路径
   */
  component?: string;
  
  /**
   * 菜单类型 - M=目录，C=菜单，F=按钮
   */
  menu_type: 'M' | 'C' | 'F';
}`
      } else if (type.name === 'sys_config.ts') {
        typeContent.value = `/**
 * 系统配置对象
 * 对应表: sys_config
 */
export interface SysConfig {
  /**
   * 配置ID - 主键
   */
  config_id: number;
  
  /**
   * 配置名称
   */
  config_name: string;
  
  /**
   * 配置键
   */
  config_key: string;
  
  /**
   * 配置值
   */
  config_value: string;
  
  /**
   * 是否系统内置配置
   * 0-否 1-是
   */
  is_builtin?: '0' | '1';
  
  /**
   * 备注
   */
  remark?: string;
}`
      } else {
        typeContent.value = `/**
 * ${type.name.replace('.ts', '')} 接口定义
 * 演示数据
 */
export interface ${type.name.replace('.ts', '')} {
  /**
   * ID
   */
  id: number;
  
  /**
   * 名称
   */
  name: string;
  
  /**
   * 创建时间
   */
  create_time?: string;
  
  /**
   * 状态
   */
  status?: '0' | '1';
}`
      }
      console.log('使用内置演示数据:', type.name);
    }
    
    contentLoading.value = false
  } catch (err) {
    contentLoading.value = false
    console.error('获取类型定义内容错误:', err)
    typeContent.value = `// 加载类型定义出错: ${err.message}
// 请检查服务端API是否正常或刷新页面重试`
  }
}

/**
 * 开始监控类型定义变化
 * 每5秒检查一次文件变化
 */
function startMonitoring() {
  if (monitorInterval) {
    clearInterval(monitorInterval)
  }
  
  monitorInterval = setInterval(checkForChanges, 5000)
  monitorStatus.value = 'active'
}

/**
 * 检查类型定义文件变化
 * 对比现有类型和最新类型列表
 */
async function checkForChanges() {
  try {
    try {
      const response = await fetch('/api/types')
      if (!response.ok) {
        console.warn('检查类型更新失败:', response.status)
        return
      }
      
      const data = await response.json()
      if (!data.types) {
        console.warn('检查类型更新返回格式错误')
        return
      }
      
      const newTypes = data.types.map(t => t.name)
      const oldTypes = types.value.map(t => t.name)
      
      // 检查是否有新增或删除的类型
      if (newTypes.length !== oldTypes.length || 
          JSON.stringify(newTypes.sort()) !== JSON.stringify(oldTypes.sort())) {
        types.value = data.types
        monitorStatus.value = 'updated'
        
        // 5秒后恢复正常状态
        setTimeout(() => {
          monitorStatus.value = 'active'
        }, 5000)
        
        return
      }
    } catch (err) {
      console.warn('监控类型变化网络错误，忽略:', err)
      return
    }
    
    // 如果当前有选中的类型，检查内容是否有更新
    if (selectedType.value) {
      try {
        const response = await fetch(`/raw-types/${selectedType.value}`)
        if (!response.ok) return
        
        const content = await response.text()
        
        if (content !== typeContent.value) {
          // 类型内容已更新
          typeContent.value = content
          
          // 添加到已修改类型列表
          if (!modifiedTypes.value.includes(selectedType.value)) {
            modifiedTypes.value.push(selectedType.value)
          }
          
          monitorStatus.value = 'updated'
          
          // 5秒后恢复正常状态
          setTimeout(() => {
            monitorStatus.value = 'active'
          }, 5000)
        }
      } catch (err) {
        console.warn('检查类型内容变化网络错误，忽略:', err)
      }
    }
  } catch (err) {
    console.error('监控类型定义变化错误(忽略):', err)
  }
}

/**
 * 手动刷新所有类型数据
 */
async function refreshTypes() {
  monitorStatus.value = 'refreshing'
  await fetchTypes()
  
  if (selectedType.value) {
    const type = types.value.find(t => t.name === selectedType.value)
    if (type) {
      await selectType(type)
    }
  }
  
  monitorStatus.value = 'active'
}

/**
 * 清除当前选中的类型
 */
function clearSelection() {
  selectedType.value = null
  typeContent.value = ''
  window.location.hash = ''
}

/**
 * 切换类型分组的展开/折叠状态
 */
function toggleGroup(prefix) {
  if (activeGroups.value.includes(prefix)) {
    activeGroups.value = activeGroups.value.filter(g => g !== prefix)
  } else {
    activeGroups.value.push(prefix)
  }
}

// 处理建议点击
function handleSuggestionClick(type) {
  searchQuery.value = type.name
  showSuggestions.value = false
  selectType(type)
}

// 处理输入框焦点
function handleSearchFocus() {
  showSuggestions.value = true
}

// 处理输入框失去焦点
function handleSearchBlur() {
  // 延迟隐藏建议，以便可以点击建议项
  setTimeout(() => {
    showSuggestions.value = false
  }, 200)
}

// 处理键盘导航
function handleSearchKeydown(event) {
  if (!showSuggestions.value || searchSuggestions.value.length === 0) return
  
  switch (event.key) {
    case 'ArrowDown':
      event.preventDefault()
      activeSuggestionIndex.value = (activeSuggestionIndex.value + 1) % searchSuggestions.value.length
      break
    case 'ArrowUp':
      event.preventDefault()
      activeSuggestionIndex.value = activeSuggestionIndex.value <= 0 
        ? searchSuggestions.value.length - 1 
        : activeSuggestionIndex.value - 1
      break
    case 'Enter':
      if (activeSuggestionIndex.value >= 0) {
        event.preventDefault()
        handleSuggestionClick(searchSuggestions.value[activeSuggestionIndex.value])
      }
      break
    case 'Escape':
      event.preventDefault()
      showSuggestions.value = false
      break
  }
}

// 当搜索查询变化时，重置建议索引并显示建议
watch(searchQuery, () => {
  activeSuggestionIndex.value = -1
  showSuggestions.value = searchQuery.value.length > 0
})

// 组件销毁时清除监控
onUnmounted(() => {
  if (monitorInterval) {
    clearInterval(monitorInterval)
  }
})
</script>

<template>
  <div class="type-viewer">
    <!-- 顶部标题和搜索栏 -->
    <div class="type-picker-header">
      <h2>类型定义</h2>
      <div class="search-box">
        <input 
          type="text" 
          v-model="searchQuery" 
          placeholder="搜索类型..."
          class="search-input"
          @focus="handleSearchFocus"
          @blur="handleSearchBlur"
          @keydown="handleSearchKeydown"
        />
        <div v-if="showSuggestions && searchSuggestions.length > 0" class="search-suggestions">
          <div 
            v-for="(suggestion, index) in searchSuggestions" 
            :key="suggestion.name"
            class="suggestion-item"
            :class="{ active: index === activeSuggestionIndex }"
            @mousedown="handleSuggestionClick(suggestion)"
            @mouseover="activeSuggestionIndex = index"
          >
            <span class="suggestion-name">{{ suggestion.name }}</span>
            <span v-if="suggestion.description" class="suggestion-desc">{{ suggestion.description }}</span>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 主体内容区域 -->
    <div class="type-content-wrapper">
      <!-- 类型选择面板 -->
      <div class="type-picker">
        <div v-if="loading" class="loading">
          加载类型中...
        </div>
        
        <div v-else-if="error" class="error">
          {{ error }}
        </div>
        
        <div v-else class="type-list">
          <div v-if="filteredTypes.length === 0" class="no-result">
            没有找到匹配的类型
          </div>
          
          <template v-else>
            <!-- 类型分组列表 -->
            <div v-for="group in typeGroups" :key="group.prefix" class="type-group">
              <div 
                class="type-group-header" 
                @click="toggleGroup(group.prefix)"
              >
                <span class="group-name">{{ group.prefix }}</span>
                <span class="count">({{ group.types.length }})</span>
                <span class="group-toggle">
                  {{ activeGroups.includes(group.prefix) ? '▼' : '▶' }}
                </span>
              </div>
              
              <div 
                v-if="activeGroups.includes(group.prefix)" 
                class="type-group-items"
              >
                <div 
                  v-for="type in group.types" 
                  :key="type.name"
                  class="type-item"
                  :class="{ active: selectedType === type.name }"
                  @click="selectType(type)"
                >
                  <span class="type-name">{{ type.name }}</span>
                  <span 
                    v-if="modifiedTypes.includes(type.name)" 
                    class="modified-badge"
                  >更新</span>
                </div>
              </div>
            </div>
          </template>
        </div>
        
        <div class="monitor-status">
          <span :class="['status-indicator', monitorStatus]"></span>
          <span class="status-text">
            {{ monitorStatus === 'active' ? '实时监控中' : 
               monitorStatus === 'updated' ? '检测到更新' : 
               monitorStatus === 'refreshing' ? '刷新中...' :
               monitorStatus === 'error' ? '监控错误' : '监控已停止' }}
          </span>
          <button 
            class="refresh-button"
            @click="refreshTypes"
            :disabled="monitorStatus === 'refreshing'"
          >
            刷新
          </button>
        </div>
      </div>
      
      <!-- 类型内容显示区域 -->
      <div class="type-content">
        <div v-if="!selectedType" class="empty-state">
          <div class="empty-icon">📄</div>
          <div class="empty-text">请从左侧选择一个类型定义查看详情</div>
        </div>
        
        <template v-else>
          <div class="type-detail-header">
            <h2 class="type-title">
              {{ selectedType }} 
              <span class="type-badge">接口定义</span>
            </h2>
            <div class="type-actions">
              <CopyButton 
                :content="typeContent" 
                label="复制" 
                successLabel="已复制!"
                title="复制类型定义到剪贴板"
                @copy-success="() => {}"
                @copy-error="(err) => console.error('复制错误:', err)"
              />
              <button 
                class="close-button"
                @click="clearSelection"
                title="关闭当前类型"
              >
                ×
              </button>
            </div>
          </div>
          
          <div v-if="contentLoading" class="content-loading">
            加载内容中...
          </div>
          
          <div v-else class="type-detail-content">
            <CodeBlock
              :code="typeContent"
              language="typescript"
              :copy-enabled="true"
              label="TypeScript"
              :show-line-numbers="true"
              max-height="calc(100vh - 250px)"
            />
          </div>
        </template>
      </div>
    </div>
  </div>
</template>

<style scoped>
.type-viewer {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 180px);
  min-height: 500px;
  border: 1px solid var(--vp-c-divider);
  border-radius: 8px;
  overflow: hidden;
  background-color: var(--vp-c-bg);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.type-picker-header {
  padding: 16px;
  border-bottom: 1px solid var(--vp-c-divider);
  background-color: var(--vp-c-bg);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.type-picker-header h2 {
  margin: 0;
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--vp-c-brand);
  white-space: nowrap;
}

.search-box {
  position: relative;
  width: 200px;
  margin-left: 16px;
}

.search-input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--vp-c-divider);
  border-radius: 4px;
  font-size: 0.9rem;
  background-color: var(--vp-c-bg);
  color: var(--vp-c-text-1);
  transition: all 0.3s;
}

.search-input:focus {
  outline: none;
  border-color: var(--vp-c-brand);
  box-shadow: 0 0 0 2px rgba(var(--vp-c-brand-rgb), 0.1);
}

.search-suggestions {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background-color: var(--vp-c-bg);
  border: 1px solid var(--vp-c-divider);
  border-radius: 4px;
  max-height: 200px;
  overflow-y: auto;
  z-index: 100;
  margin-top: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.suggestion-item {
  padding: 8px 12px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  border-bottom: 1px solid var(--vp-c-divider-light);
}

.suggestion-item:last-child {
  border-bottom: none;
}

.suggestion-item.active,
.suggestion-item:hover {
  background-color: rgba(var(--vp-c-brand-rgb), 0.1);
}

.suggestion-name {
  font-weight: 500;
  color: var(--vp-c-text-1);
}

.suggestion-desc {
  font-size: 0.8rem;
  color: var(--vp-c-text-2);
  margin-top: 2px;
}

.type-content-wrapper {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.type-picker {
  width: 260px;
  min-width: 200px;
  border-right: 1px solid var(--vp-c-divider);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background-color: var(--vp-c-bg-alt);
}

.type-content {
  flex: 1;
  overflow-y: auto;
  padding: 0;
  position: relative;
  min-width: 0; /* 确保弹性布局中内容不会溢出 */
  background-color: var(--vp-c-bg);
}

.type-group {
  margin-bottom: 4px;
}

.type-group-header {
  display: flex;
  align-items: center;
  padding: 8px 16px;
  cursor: pointer;
  font-weight: 600;
  color: var(--vp-c-text-1);
  user-select: none;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.type-group-header:hover {
  background-color: rgba(var(--vp-c-brand-rgb), 0.1);
}

.group-name {
  flex: 1;
}

.count {
  color: var(--vp-c-text-2);
  font-size: 0.85rem;
  margin-right: 8px;
  background-color: var(--vp-c-bg);
  padding: 2px 6px;
  border-radius: 10px;
  font-weight: normal;
}

.group-toggle {
  font-size: 0.8rem;
  width: 16px;
  text-align: center;
  transition: transform 0.2s;
}

.type-group-items {
  max-height: 300px;
  overflow-y: auto;
  margin-left: 8px;
}

.type-item {
  display: flex;
  align-items: center;
  padding: 8px 16px 8px 24px;
  cursor: pointer;
  font-size: 0.9rem;
  border-left: 2px solid transparent;
  position: relative;
  border-radius: 0 4px 4px 0;
  transition: all 0.2s;
  margin: 2px 0;
}

.type-item:hover {
  background-color: rgba(var(--vp-c-brand-rgb), 0.05);
}

.type-item.active {
  background-color: rgba(var(--vp-c-brand-rgb), 0.1);
  border-left-color: var(--vp-c-brand);
  font-weight: 600;
  color: var(--vp-c-brand);
}

.type-name {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.modified-badge {
  display: inline-block;
  font-size: 0.7rem;
  background-color: var(--vp-c-brand);
  color: white;
  padding: 2px 6px;
  border-radius: 10px;
  margin-left: 8px;
  font-weight: normal;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% {
    opacity: 0.6;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0.6;
  }
}

.monitor-status {
  padding: 12px 16px;
  border-top: 1px solid var(--vp-c-divider);
  display: flex;
  align-items: center;
  justify-content: space-between;
  background-color: var(--vp-c-bg);
}

.status-indicator {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  margin-right: 8px;
  position: relative;
}

.status-indicator.active {
  background-color: var(--vp-c-green);
  box-shadow: 0 0 0 4px rgba(var(--vp-c-green-rgb), 0.2);
}

.status-indicator.updated {
  background-color: var(--vp-c-yellow);
  box-shadow: 0 0 0 4px rgba(var(--vp-c-yellow-rgb), 0.2);
}

.status-indicator.refreshing {
  background-color: var(--vp-c-gray-light-3);
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.status-indicator.error {
  background-color: var(--vp-c-red);
  box-shadow: 0 0 0 4px rgba(var(--vp-c-red-rgb), 0.2);
}

.status-text {
  font-size: 0.85rem;
  color: var(--vp-c-text-2);
}

.refresh-button {
  background: none;
  border: none;
  padding: 6px 10px;
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--vp-c-brand);
  border-radius: 4px;
  transition: all 0.2s;
}

.refresh-button:hover {
  background-color: rgba(var(--vp-c-brand-rgb), 0.1);
}

.refresh-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.type-detail-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: var(--vp-c-bg);
  padding: 16px 24px;
  border-bottom: 1px solid var(--vp-c-divider);
  display: flex;
  align-items: center;
  justify-content: space-between;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.type-title {
  margin: 0;
  font-size: 1.2rem;
  display: flex;
  align-items: center;
  gap: 8px;
}

.type-badge {
  background-color: var(--vp-c-brand);
  color: white;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 0.8rem;
  font-weight: normal;
}

.type-actions {
  display: flex;
  gap: 8px;
}

.close-button {
  background: none;
  border: none;
  padding: 4px 8px;
  cursor: pointer;
  font-size: 1.2rem;
  color: var(--vp-c-text-2);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}

.close-button:hover {
  background-color: rgba(var(--vp-c-brand-rgb), 0.1);
  color: var(--vp-c-brand);
}

.content-loading {
  padding: 40px 20px;
  text-align: center;
  color: var(--vp-c-text-2);
  font-size: 0.9rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 200px;
}

.content-loading::after {
  content: '';
  display: block;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid var(--vp-c-divider);
  border-top-color: var(--vp-c-brand);
  animation: spin 1s linear infinite;
  margin-top: 16px;
}

.empty-state {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100%;
  padding: 32px;
  text-align: center;
  color: var(--vp-c-text-2);
}

.empty-icon {
  font-size: 4rem;
  margin-bottom: 16px;
  color: var(--vp-c-text-3);
}

.empty-text {
  margin: 0;
  color: var(--vp-c-text-2);
  font-size: 1.1rem;
  max-width: 400px;
}

.loading, .error, .no-result {
  padding: 20px;
  text-align: center;
  color: var(--vp-c-text-2);
  font-size: 0.9rem;
}

.error {
  color: var(--vp-c-red);
  background-color: rgba(var(--vp-c-red-rgb), 0.1);
  border-radius: 4px;
  padding: 16px;
  margin: 16px;
}

.type-detail-content {
  padding: 0;
}

/* 适配暗黑模式和亮色模式 */
@media (prefers-color-scheme: dark) {
  .type-viewer {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  }
}

/* 适配大屏幕 - 增加内容区域比例 */
@media (min-width: 1200px) {
  .type-picker {
    width: 240px;
  }
  
  .type-content {
    flex: 3;
  }
}

/* 适配中等屏幕 */
@media (max-width: 992px) {
  .type-picker {
    width: 220px;
  }
}

/* 适配小屏幕和移动设备 */
@media (max-width: 768px) {
  .type-viewer {
    height: auto;
    min-height: 600px;
  }
  
  .type-content-wrapper {
    flex-direction: column;
  }
  
  .type-picker {
    width: 100%;
    max-height: 300px;
    border-right: none;
    border-bottom: 1px solid var(--vp-c-divider);
  }
  
  .type-content {
    height: calc(100vh - 400px);
  }
  
  .type-picker-header {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .search-box {
    width: 100%;
    margin-left: 0;
    margin-top: 12px;
  }
}
</style> 